//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   Materials.hh
 * \author Jeremy Roberts
 * \date   10/26/2010
 * \brief  A set of material cross-sections.
 * \note   Copyright (C) 2010 Jeremy Roberts
 */
//---------------------------------------------------------------------------//
// $Rev:: 123                                           $:Rev of last commit
// $Author:: j.alyn.roberts@gmail.com                   $:Author of last commit
// $Date:: 2011-08-25 12:30:43 +0000 (Thu, 25 Aug 2011) $:Date of last commit
//---------------------------------------------------------------------------//

#ifndef MATERIALS_HH
#define MATERIALS_HH

#include <vector>
#include <string>

#include "material/Cross_Section.hh"
#include "tran/Definitions.hh"
#include "../utilities/DBC.hh"
#include "../utilities/SP.hh"

namespace slabtran
{

//===========================================================================//
/*!
 * \class Materials
 * \brief Material cross-section data container.
 *
 *  This class is a container for cross-section data.  It holds the data
 *  for each material.  Each material has an associated
 *  index, and these index values are assigned to mesh cells.  This class
 *  can be consider a "working library" of data.
 *
 *  This class is only a container for underlying \ref Cross_Sections
 *  objects, which hold data for a single material.
 *
 *  An adjoint flag exists so that appropriate groups can be selected in
 *  scattering matrices for forward or adjoint calculations.
 *
 *  \sa Cross_Sections
 *
 */
//===========================================================================//
 
class Materials
{

public:

  /// \name Typedefs
  //\{
  /// Smart pointer to materials library
  typedef util::SP<Materials>       SP_materials;
  /// Cross section class
  typedef Cross_Section             XS;
  /// Smart pointer to cross section class
  typedef util::SP<XS>              SP_XS;
  /// Vector of cross section smart pointers
  typedef std::vector<SP_XS>        Vec_XS;
  //\}

  /*!
   *  \brief Constructor.
   *
   *  \param number_groups      number of energy groups
   *  \param number_materials   number of materials
   */
  explicit Materials(int number_mats, std::string name = "");

  // >>> PUBLIC INTERFACE

  /// Return the total number of materials in the problem.
  int number_materials() const { return d_number_materials; }

  /// Query adjoint.
  int adjoint() const { return d_adjoint; }

  /*!
   *  \brief Set adjoint flag.
   *
   *  This sets the appropriate bounds for the scattering matrix
   *  in each cross-section.  The cross-sections \em must already
   *  exist.
   *
   *  \param adjoint true for an adjoint calculation
   */
  void set_adjoint(int adjoint);

  /*
   *  \brief Assign material cross sections to an id.
   *
   *  \param xs     smart pointer to cross-section object to add
   *  \param xs_id  id of a material
   */
  void assign(SP_XS xs, int xs_id);

  /*
   *  \brief Check to see if cross sections are assigned to a material.
   *
   *  \param xs_id  id of a material
   */
  bool assigned(int xs_id) const;

  /*  \brief Get the (const) cross-sections for a material.
   *
   *  \param xs_id  material id of desired data
   *  \param g      group of desired data
   *  \return       smart pointer to cross-section object
   */
  const XS& get(int xs_id) const;

  /*  \brief Get the (mutable) cross-sections for a material.
   *
   *  Accessing the mutable cross-sections via reference is useful when
   *  setting \ref d_xs.
   *
   *  \param xs_id  material id of desired data
   *  \param g      group of desired data
   *  \return       smart pointer to cross-section object
   */
  XS& get(int xs_id);

  /*  \brief Get SP to cross-sections for a material.
   *
   *  Accessing the cross-sections via smart pointer.
   *
   *  \param xs_id  material id of desired data
   *  \param g      group of desired data
   *  \return       smart pointer to cross-section object
   */
  SP_XS& get_p(int xs_id);

  /// Print the data
  void print() const;

private:

  // >>> DATA

  /// Number of materials in the problem
  const int d_number_materials;

  /// Name of working library
  const std::string d_name;

  /// Adjoint flag
  int d_adjoint;

  /// Cross section data for each material.
  Vec_XS d_xs;

};

} // end namespace slabtran

//---------------------------------------------------------------------------//
// INLINE FUNCTIONS
//---------------------------------------------------------------------------//

#include "material/Materials.i.hh"

#endif // MATERIALS_HH

//---------------------------------------------------------------------------//
//                 end of Materials.hh
//---------------------------------------------------------------------------//

